import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpException,
  Inject
} from '@nestjs/common'
import dayjs from 'dayjs'
import { WinstonLogger, WINSTON_MODULE_LOGGER } from '@ttou/nest-winston'
import { IRequest, IResponse } from '@/common/interfaces'

interface ExceptionResponse {
  statusCode: number
  message: any
  error: any
}

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  constructor(
    @Inject(WINSTON_MODULE_LOGGER)
    private logger: WinstonLogger
  ) {}

  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp()
    const req = ctx.getRequest<IRequest>()
    const res = ctx.getResponse<IResponse>()
    let status = exception.getStatus()
    let message = exception.message
    let error = exception.stack

    if (exception.getResponse()) {
      const response = exception.getResponse() as ExceptionResponse
      status = response.statusCode
      error = response.error
      message = response.message
    }

    if (![401, 403, 404].includes(status)) {
      this.logger.error(`${error}: ${message}`, null, HttpException.name)
    }

    res.status(status).send({
      timestamp: dayjs().format('YYYY-MM-DD HH:mm:ss.SSS'),
      path: req.url,
      status,
      error,
      message
    })
  }
}
